﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom;
using System.Xaml;
using System.Reflection;

namespace NeuroSpeech.XamlExtensions
{
    public class XamlCodeContext
    {

        public XamlSchemaContext SchemaContext { get; private set; }
        public Stack<XamlItem> Stack { get; private set; }
        public CodeNamespace Namespace { get; private set; }
        public CodeTypeDeclaration Type { get; private set; }
        public List<CodeStatement> Statements { get; private set; }
        public List<CodeStatement> PreStatements { get; private set; }
        public List<CodeStatement> PostStatements { get; private set; }
        public StringBuilder Warnings { get; private set; }

        //public XamlValue XamlValue { get; private set; }

        public XamlMember Member {
            get {
                return Peek.Member;
            }
        }


        public XamlItem Peek
        {
            get
            {
                return Stack.Peek();
            }
        }

        public XamlCodeContext(
                XamlSchemaContext schemaContext,
                StringBuilder warnings,
                Stack<XamlItem> stack,
                CodeNamespace ns,
                CodeTypeDeclaration type,
                List<CodeStatement> initMethod,
                List<CodeStatement> preStatements,
                List<CodeStatement> postStatements
            )
        {
            SchemaContext = schemaContext;
            Warnings = warnings;
            Stack = stack;
            Namespace = ns;
            Type = type;
            Statements = initMethod;
            PostStatements = postStatements;
            PreStatements = preStatements;
        }


        #region internal CodeVariableDeclarationStatement GetLastStatement<T1>()
        public T GetLastStatement<T>(List<CodeStatement> statements)
            where T : class
        {
            int count = statements.Count - 1;
            for (int i = count; i >= 0; i--)
            {
                object cs = statements[i];
                if (cs is T)
                {
                    return cs as T;
                }
            }
            return null;
        }
        #endregion

        public CodeExpression ParentTarget(CodeExpression exp){
            CodePropertyReferenceExpression pr = exp as CodePropertyReferenceExpression;
            if (pr != null)
                return pr.TargetObject;
            CodeFieldReferenceExpression fr = exp as CodeFieldReferenceExpression;
            if (fr != null)
                return fr.TargetObject;
            CodeMethodReferenceExpression mr = exp as CodeMethodReferenceExpression;
            if (mr != null)
                return mr.TargetObject;
            return exp;
        }

    }
}
